package cn.wolfcode.web.controller;

import cn.wolfcode.common.domain.UserInfo;
import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.common.web.anno.RequireLogin;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.mq.OrderMessage;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.IOrderInfoService;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.util.DateUtil;
import cn.wolfcode.util.UserUtil;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import com.alibaba.druid.sql.visitor.functions.Bin;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.ConcurrentHashMap;


@RestController
@RequestMapping("/order")
@Slf4j
public class OrderInfoController {
    @Autowired
    private ISeckillProductService seckillProductService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private IOrderInfoService orderInfoService;

    public static ConcurrentHashMap<Long,Boolean> local_flag = new ConcurrentHashMap<>();

    @RequestMapping("/doSeckill")
    // 1 判断他是否有登录  贴@RequireLogin
    @RequireLogin
    public Result<String> doSeckill(Integer time, Long seckillId, HttpServletRequest request) {
        // 2 做参数校验
        if (StringUtils.isEmpty(time +"") || StringUtils.isEmpty(seckillId + "")) {
            // 抛异常 非法操作
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }
        // 判断本地标识,如果本地标识为true,表示redis减少到了负数
        Boolean isFlag = local_flag.get(seckillId);
        if (isFlag != null && isFlag) {
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }
        // 3 判断是否在秒杀活动时间范围内  判断完,不在在三个时间段,注释这段代码
        SeckillProductVo seckillProductVo = seckillProductService.find(time,seckillId);
        /*boolean legalTime = DateUtil.isLegalTime(seckillProductVo.getStartDate(),time);
        if(!legalTime){
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }*/
        //
        // 4 判断库存是否足够
        if (seckillProductVo.getStockCount() < 0) {
            // 来晚了
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
        // 5 判断用户是否有重复下单
        /**
         *  string   seckillOrder:phone:seckillId   true
         *  hash   seckillOrderHash:time  phone:seckillId
         *  set seckillOrderSet:time  phone:seckillId  isMember
         *  set 中有个isMember方法判断是否有某一个元素在集合中
         */
        String token = request.getHeader("token");
        UserInfo userInfo = UserUtil.getUser(redisTemplate,token);
        Boolean flag = redisTemplate.opsForSet().isMember(SeckillRedisKey.SECKILL_ORDER_SET.getRealKey(time + ""), userInfo.getPhone() + ":" + seckillId);
        if (flag) {
            // 您已经抢购到商品了，请不要重复抢购
            throw new BusinessException(SeckillCodeMsg.REPEAT_SECKILL);
        }

        // 利用redis控制进入到service人数
        Long count = redisTemplate.opsForHash().increment(SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(time + ""),seckillId + "" ,-1);
        if (count <0 ){
            local_flag.put(seckillId,true);
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }

        // 6 秒杀业务逻辑
        //String orderNo = orderInfoService.doSeckill(time,seckillId,userInfo.getPhone());
        //return Result.success(orderNo);
        //6.1减少真实库存
        //6.2创建订单并且把订单保存到数据库中  t_order_info
        //6.3redis存一个数据为重复下单做铺垫

        // 把数据封装成消息发送到 MQ 中
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setSeckillId(seckillId);
        orderMessage.setTime(time);
        orderMessage.setUserPhone(userInfo.getPhone());
        orderMessage.setToken(token);
        rocketMQTemplate.sendOneWay(MQConstant.ORDER_PEDDING_TOPIC,orderMessage);
        return Result.success("正在抢购中,请稍后");
    }

    @RequestMapping("/find")
    public Result<OrderInfo> find(String orderNo,HttpServletRequest request) {
        if (StringUtils.isEmpty(orderNo)) {
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }
        OrderInfo orderInfo = orderInfoService.find(orderNo);
        // 如果等于空 可能是本人伪造的订单信息
        if (orderInfo == null) {
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }
        // 当前登录用户只能看到自己的订单信息
        String token = request.getHeader("token");
        UserInfo user = UserUtil.getUser(redisTemplate, token);
        if (!user.getPhone().equals(orderInfo.getUserId())) {
            throw new BusinessException(SeckillCodeMsg.OPT_ERROR);
        }
        return Result.success(orderInfo);
    }
}
